﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PKTools.Statistical
{
    class Statistical
    {
        public static double Moment(double[] x, int r)
        {
            if (x.Length == 0)
                throw new Exception("zero array length");

            return x.Sum(e => Math.Pow(e, r)) / x.Length;
        }

        public static double Variance(double[] x)
        {
            return Moment(x, 2) - Math.Pow(x.Average(), 2);
        }

        public static double StandardDeviation(double[] x)
        {
            return Math.Pow(Variance(x), 0.5);
        }

        public static double Covariance(double[] x, double[] y)
        {
            if (x.Length != y.Length)
                throw new Exception("arrays length not equal");

            double
                n = 0,
                xAvg = x.Average(),
                yAvg = y.Average();

            for (var i = 0; i < x.Length; i++)
                n += (x[i] - xAvg) * (y[i] - yAvg);

            return n / x.Length;
        }

        const double
            zero = 0.000001;

        public static double Correlation(double[] x, double[] y)
        {
            double
                covariance = Covariance(x, y),
                xStdDev = StandardDeviation(x),
                yStdDev = StandardDeviation(y),
                n = xStdDev * yStdDev;

            return Math.Abs(n) > zero ? covariance / n : 0;
        }
    }
}
